using System;
using OracleInternal.Common;
using OracleInternal.I18N;

namespace OracleInternal.Network
{
	internal class AcceptPacket : Packet
	{
		private byte[] m_AcceptData;

		private bool m_AcceptDataOF;

		internal AcceptPacket(Packet pkt)
			: base(pkt)
		{
			m_sessionCtx.m_myversion = m_dataBuffer[TNSPacketOffsets.NSPACVSN] & 0xFF;
			m_sessionCtx.m_myversion <<= 8;
			m_sessionCtx.m_myversion |= m_dataBuffer[TNSPacketOffsets.NSPACVSN + 1] & 0xFF;
			m_sessionCtx.m_negotiatedOptions = m_dataBuffer[TNSPacketOffsets.NSPACOPT] & 0xFF;
			m_sessionCtx.m_negotiatedOptions <<= 8;
			m_sessionCtx.m_negotiatedOptions |= m_dataBuffer[TNSPacketOffsets.NSPACOPT + 1] & 0xFF;
			if (m_sessionCtx.m_myversion < SessionContext.NSVSNLSD)
			{
				m_sessionCtx.m_sessionDataUnit = m_dataBuffer[TNSPacketOffsets.NSPACSDU] & 0xFF;
				m_sessionCtx.m_sessionDataUnit <<= 8;
				m_sessionCtx.m_sessionDataUnit |= m_dataBuffer[TNSPacketOffsets.NSPACSDU + 1] & 0xFF;
				m_sessionCtx.m_transportDataUnit = m_dataBuffer[TNSPacketOffsets.NSPACTDU] & 0xFF;
				m_sessionCtx.m_transportDataUnit <<= 8;
				m_sessionCtx.m_transportDataUnit |= m_dataBuffer[TNSPacketOffsets.NSPACTDU + 1] & 0xFF;
			}
			else
			{
				m_sessionCtx.m_sessionDataUnit = m_dataBuffer[TNSPacketOffsets.NSPACLSD] & 0xFF;
				m_sessionCtx.m_sessionDataUnit <<= 8;
				m_sessionCtx.m_sessionDataUnit |= m_dataBuffer[TNSPacketOffsets.NSPACLSD + 1] & 0xFF;
				m_sessionCtx.m_sessionDataUnit <<= 8;
				m_sessionCtx.m_sessionDataUnit |= m_dataBuffer[TNSPacketOffsets.NSPACLSD + 2] & 0xFF;
				m_sessionCtx.m_sessionDataUnit <<= 8;
				m_sessionCtx.m_sessionDataUnit |= m_dataBuffer[TNSPacketOffsets.NSPACLSD + 3] & 0xFF;
				m_sessionCtx.m_transportDataUnit = m_dataBuffer[TNSPacketOffsets.NSPACLTD] & 0xFF;
				m_sessionCtx.m_transportDataUnit <<= 8;
				m_sessionCtx.m_transportDataUnit |= m_dataBuffer[TNSPacketOffsets.NSPACLTD + 1] & 0xFF;
				m_sessionCtx.m_transportDataUnit <<= 8;
				m_sessionCtx.m_transportDataUnit |= m_dataBuffer[TNSPacketOffsets.NSPACLTD + 2] & 0xFF;
				m_sessionCtx.m_transportDataUnit <<= 8;
				m_sessionCtx.m_transportDataUnit |= m_dataBuffer[TNSPacketOffsets.NSPACLTD + 3] & 0xFF;
			}
			m_sessionCtx.m_hisone = (ushort)(m_dataBuffer[TNSPacketOffsets.NSPACONE] & 0xFFu);
			m_sessionCtx.m_hisone <<= 8;
			m_sessionCtx.m_hisone |= (ushort)(m_dataBuffer[TNSPacketOffsets.NSPACONE + 1] & 0xFF);
			m_dataLength = m_dataBuffer[TNSPacketOffsets.NSPACLEN] & 0xFF;
			m_dataLength <<= 8;
			m_dataLength |= m_dataBuffer[TNSPacketOffsets.NSPACLEN + 1] & 0xFF;
			m_dataOffset = m_dataBuffer[TNSPacketOffsets.NSPACOFF] & 0xFF;
			m_dataOffset <<= 8;
			m_dataOffset |= m_dataBuffer[TNSPacketOffsets.NSPACOFF + 1] & 0xFF;
			m_sessionCtx.m_ACFL0 = m_dataBuffer[TNSPacketOffsets.NSPACFL0];
			m_sessionCtx.m_ACFL1 = m_dataBuffer[TNSPacketOffsets.NSPACFL1];
			if (m_sessionCtx.m_myversion >= 310)
			{
				int num = m_dataBuffer[TNSPacketOffsets.NSPACADL] & 0xFF;
				num <<= 8;
				num |= m_dataBuffer[TNSPacketOffsets.NSPACADL + 1] & 0xFF;
				if (num > 0)
				{
					int num2 = m_dataBuffer[TNSPacketOffsets.NSPACAOF] & 0xFF;
					num2 <<= 8;
					num2 |= m_dataBuffer[TNSPacketOffsets.NSPACAOF + 1] & 0xFF;
					m_sessionCtx.m_reconAddr = Conv.GetInstance(871).ConvertBytesToString(m_dataBuffer, num2, num);
					if ((m_flags & Packet.NSPFSID) > 0)
					{
						m_length -= Packet.NSPSID_SZ;
						m_sessionCtx.m_SID = new byte[Packet.NSPSID_SZ];
						Buffer.BlockCopy(m_dataBuffer, m_length, m_sessionCtx.m_SID, 0, Packet.NSPSID_SZ);
					}
				}
			}
			ExtractData();
			if (m_sessionCtx.m_transportDataUnit < m_sessionCtx.m_sessionDataUnit)
			{
				m_sessionCtx.m_sessionDataUnit = m_sessionCtx.m_transportDataUnit;
			}
		}

		internal AcceptPacket(SessionContext sessCtx, string AcceptData)
			: base(sessCtx)
		{
			int num = AcceptData?.Length ?? 0;
			int num2 = ((m_sessionCtx.m_myversion < SessionContext.NSVSNLSD) ? TNSPacketOffsets.NSPACDAT : TNSPacketOffsets.NSPACV315DAT);
			if (AcceptData != null)
			{
				m_AcceptData = Conv.GetInstance(871).ConvertStringToBytes(AcceptData, 0, AcceptData.Length);
				m_AcceptDataOF = ((AcceptData.Length >= TNSPacketOffsets.NSPMXCDATA) ? true : false);
				if (!m_AcceptDataOF)
				{
					num2 += AcceptData.Length;
				}
			}
			CreateBuffer(num2, 2, 0, sessCtx);
			m_dataBuffer[TNSPacketOffsets.NSPACVSN] = (byte)((uint)(sessCtx.m_myversion / 256) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPACVSN + 1] = (byte)((uint)(sessCtx.m_myversion % 256) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPACOPT] = (byte)((uint)(sessCtx.m_options / 256) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPACOPT + 1] = (byte)((uint)(sessCtx.m_options % 256) & 0xFFu);
			int sessionDataUnit = sessCtx.m_sessionDataUnit;
			int transportDataUnit = sessCtx.m_transportDataUnit;
			int num3 = ((sessionDataUnit > ConnectionOption.NSPOLDMXSDULN) ? ConnectionOption.NSPOLDMXSDULN : sessionDataUnit);
			int num4 = ((transportDataUnit > ConnectionOption.NSPOLDMXTDULN) ? ConnectionOption.NSPOLDMXTDULN : transportDataUnit);
			m_dataBuffer[TNSPacketOffsets.NSPACSDU] = (byte)(num3 / 256);
			m_dataBuffer[TNSPacketOffsets.NSPACSDU + 1] = (byte)(num3 % 256);
			m_dataBuffer[TNSPacketOffsets.NSPACTDU] = (byte)(num4 / 256);
			m_dataBuffer[TNSPacketOffsets.NSPACTDU + 1] = (byte)(num4 % 256);
			if (m_sessionCtx.m_myversion >= SessionContext.NSVSNLSD)
			{
				m_dataBuffer[TNSPacketOffsets.NSPACLSD + 3] = (byte)((uint)sessionDataUnit & 0xFFu);
				m_dataBuffer[TNSPacketOffsets.NSPACLSD + 2] = (byte)((uint)HelperClass.URShift(sessionDataUnit, 8) & 0xFFu);
				m_dataBuffer[TNSPacketOffsets.NSPACLSD + 1] = (byte)((uint)HelperClass.URShift(sessionDataUnit, 16) & 0xFFu);
				m_dataBuffer[TNSPacketOffsets.NSPACLSD] = (byte)((uint)HelperClass.URShift(sessionDataUnit, 24) & 0xFFu);
				m_dataBuffer[TNSPacketOffsets.NSPACLTD + 3] = (byte)((uint)transportDataUnit & 0xFFu);
				m_dataBuffer[TNSPacketOffsets.NSPACLTD + 2] = (byte)((uint)HelperClass.URShift(transportDataUnit, 8) & 0xFFu);
				m_dataBuffer[TNSPacketOffsets.NSPACLTD + 1] = (byte)((uint)HelperClass.URShift(transportDataUnit, 16) & 0xFFu);
				m_dataBuffer[TNSPacketOffsets.NSPACLTD] = (byte)((uint)HelperClass.URShift(transportDataUnit, 24) & 0xFFu);
			}
			m_dataBuffer[TNSPacketOffsets.NSPACONE] = (byte)((uint)(sessCtx.m_ourone >> 8) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPACONE + 1] = (byte)(sessCtx.m_ourone & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPACLEN] = (byte)(num / 256);
			m_dataBuffer[TNSPacketOffsets.NSPACLEN + 1] = (byte)(num % 256);
			byte b = ((m_sessionCtx.m_myversion < SessionContext.NSVSNLSD) ? TNSPacketOffsets.NSPACDAT : TNSPacketOffsets.NSPACV315DAT);
			m_dataBuffer[TNSPacketOffsets.NSPACOFF + 1] = b;
			m_dataBuffer[TNSPacketOffsets.NSPACFL0] = TNSPacketOffsets.NSINADISABLEFORCONNECTION;
			m_dataBuffer[TNSPacketOffsets.NSPACFL1] = TNSPacketOffsets.NSINADISABLEFORCONNECTION;
			if (m_sessionCtx.m_bAnoEnabled)
			{
				m_dataBuffer[TNSPacketOffsets.NSPACFL0] = (byte)m_sessionCtx.m_ano.m_naFlags;
				m_dataBuffer[TNSPacketOffsets.NSPACFL1] = (byte)m_sessionCtx.m_ano.m_naFlags;
			}
			else
			{
				m_dataBuffer[TNSPacketOffsets.NSPACFL0] = TNSPacketOffsets.NSINADISABLEFORCONNECTION;
				m_dataBuffer[TNSPacketOffsets.NSPACFL1] = TNSPacketOffsets.NSINADISABLEFORCONNECTION;
			}
			if (AcceptData != null && !m_AcceptDataOF && m_AcceptData.Length != 0)
			{
				Buffer.BlockCopy(m_AcceptData, 0, m_dataBuffer, b, m_AcceptData.Length);
			}
		}

		internal override void Send()
		{
			base.Send();
			if (m_AcceptDataOF)
			{
				DataPacket dataPacket = new DataPacket(m_sessionCtx, m_AcceptData.Length + Packet.NSPOVR_SZ);
				dataPacket.PutDataInBuffer(m_AcceptData, 0, m_AcceptData.Length);
				dataPacket.Send();
			}
		}
	}
}
